package eerbaar.v2.pattern.client.internal.ui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.util.HashMap;
import java.util.Map;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import eerbaar.shared.tree.INode;

@SuppressWarnings("serial")
public class ProgramValuePanel extends JPanel {

    private String program = "";
    private final INode node;
    private final INode patternNode;
    private int height = 50;
    private boolean showExtra;

    private JLabel labelProgram;
    private JLabel labelValue;
    private JSlider slider;
    private JList comboShape;
    private final IValuePanelListener listener;

    public ProgramValuePanel(String program, INode pNode, INode patternNode,
            IValuePanelListener listener) {
        this.program = program;
        this.node = pNode;
        this.patternNode = patternNode;
        this.listener = listener;
        addComponents();
        initComponents();
        setupLink();
    }

    private void addComponents() {

        this.labelValue = new JLabel();
        this.labelProgram = new JLabel();
        this.slider = new JSlider();
        this.comboShape = new JList();
        this.comboShape.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        add(this.labelValue);
        add(this.slider);
        add(this.labelProgram);
        add(this.comboShape);

        this.slider.setMajorTickSpacing(1);
        this.slider.setMaximum(9);
        this.slider.setMinorTickSpacing(1);
        this.slider.setSnapToTicks(true);

        this.labelProgram.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                labelProgramMouseClicked(evt);
            }
        });
        this.slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                ProgramValuePanel.this.stateChanged(e);
            }
        });

        this.comboShape.setModel(new DefaultComboBoxModel(new String[] {
                "Long Range", "Short Range", "Adjustable", "+ and -" }));
        this.comboShape.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                comboShapeActionPerformed(e);
            }
        });
        this.comboShape.setVisibleRowCount(4);

    }

    private void comboShapeActionPerformed(ListSelectionEvent evt) {
        int value = this.comboShape.getSelectedIndex();
        this.setPattern(value);
    }

    private int getPatternValue() {
        int value = this.patternNode.getAttributes().get(Integer.class, "pri");
        return value;
    }

    private int getValue() {
        int value = this.node.getAttributes().get(Integer.class, "pri");
        return value;
    }

    private void initComponents() {
        setLayout(null);

        if (this.showExtra) {
            this.height = 110;
            this.comboShape.setVisible(true);
        } else {
            this.height = 25;
            this.comboShape.setVisible(false);
        }

        int value = getValue();
        this.slider.setValue(value);
        this.labelValue.setText("" + value);
        this.labelProgram.setText("" + this.program);
        int pattern = this.getPatternValue();
        this.comboShape.setSelectedIndex(pattern);

        setPreferredSize(new Dimension(200, this.height));

        this.labelValue.setBounds(0, 0, 10, 20);
        this.slider.setBounds(10, 0, 95, 20);
        this.labelProgram.setBounds(110, 0, 100, 20);
        this.comboShape.setBounds(0, 25, 110, 73);
    }

    private void labelProgramMouseClicked(java.awt.event.MouseEvent evt) {
        this.showExtra = !this.showExtra;
        this.initComponents();
        this.listener.onSizeChanged();
    }

    private void setPattern(int value) {
        this.patternNode.getAttributes().set(Integer.class, "pri", value);
    }

    private void setupLink() {

        Font font = this.labelProgram.getFont();
        Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();
        map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
        font = font.deriveFont(map);
        this.labelProgram.setFont(font);

        this.labelProgram.setForeground(Color.BLUE);
        this.labelProgram.setCursor(new Cursor(Cursor.HAND_CURSOR));
    }

    private void setValue(int value) {
        this.node.getAttributes().set(Integer.class, "pri", value);
    }

    private void stateChanged(ChangeEvent e) {
        int value = this.slider.getValue();
        this.labelValue.setText("" + value);
        this.setValue(value);
    }

}